/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using DaveSexton.DocProject.Resources;

namespace DaveSexton.DocProject.Engine
{
	public class CopyFileBuildStep<TEngine> : BuildStep<TEngine>
		where TEngine : IBuildEngine
	{
		#region Public Properties
		public override string Name
		{
			get
			{
				return "Copy File";
			}
		}

		public string Source
		{
			get
			{
				return source;
			}
		}

		public string Target
		{
			get
			{
				return target;
			}
		}

		public bool DeleteSource
		{
			get
			{
				return deleteSource;
			}
			set
			{
				deleteSource = value;
			}
		}

		public bool Overwrite
		{
			get
			{
				return overwrite;
			}
			set
			{
				overwrite = value;
			}
		}
		#endregion

		#region Private / Protected
		private readonly string source, target;
		private bool deleteSource;
		private bool overwrite = true;
		private volatile bool canceled;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="CopyFileBuildStep" /> class.
		/// </summary>
		public CopyFileBuildStep(TEngine engine, string source, string target)
			: this(engine, false, source, target, false)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyFileBuildStep" /> class.
		/// </summary>
		public CopyFileBuildStep(TEngine engine, bool continueOnError, string source, string target)
			: this(engine, continueOnError, source, target, false)
		{

		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyFileBuildStep" /> class.
		/// </summary>
		public CopyFileBuildStep(TEngine engine, string source, string target, bool deleteSource)
			: this(engine, false, source, target, deleteSource)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyFileBuildStep" /> class.
		/// </summary>
		public CopyFileBuildStep(TEngine engine, bool continueOnError, string source, string target, bool deleteSource)
			: base(engine)
		{
			if (string.IsNullOrEmpty(source))
				throw new ArgumentException(Errors.NullOrEmpty, "source");

			if (string.IsNullOrEmpty(target))
				throw new ArgumentException(Errors.NullOrEmpty, "target");

			this.source = source;
			this.target = target;
			this.deleteSource = deleteSource;
			ContinueOnError = continueOnError;
		}
		#endregion

		#region Methods
		protected override void ExecuteInternal(BuildContext context)
		{
			context.TraceLine();
			context.TraceLine(ToString());

			if (deleteSource && !overwrite)
				// this method will not overwrite a file
				File.Move(source, target);
			else
			{
				File.Copy(source, target, overwrite);

				if (canceled)
				{
					// reset private canceled field in case the step is reused
					canceled = false;
					return;
				}

				if (deleteSource)
					File.Delete(source);
			}
		}

		protected override void CancelInternal(BuildContext context)
		{
			canceled = true;
		}

		public override string ToString()
		{
			StringBuilder text = new StringBuilder();

			text.Append((deleteSource) ? "Move" : "Copy");

			text.Append(" \"" + source + "\" to \"" + target + "\"");

			if (overwrite)
				text.Append(" and overwrite.");
			else
				text.Append(".");
			
			return text.ToString();
		}
		#endregion
	}
}
